package com.changgou.gateway.filter;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * 老大哥在看着你
 *
 * @author ANG.YU
 * @date 2019-10-21 10:11
 * 全局过滤器拦截客户端的全部请求。校验用户是否登陆
 */
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
    public static final String Authorization = "Authorization";
    public static final String USERKEY = "userKey";
    public static final String LOCALURL = "http://login.changgou.com:9200/login?ReturnUrl=";
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        /*获取响应和请求*/
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        /*设置过滤，有些请求不拦截*/
        String path = request.getURI().getPath();
        /*判断情求路径是否包含/login*/
        if (!path.contains("/login")) {
            HttpCookie cookie = request.getCookies().getFirst(USERKEY);
            if (null != cookie) {
                String value = cookie.getValue();
                if (!StringUtils.isEmpty(value)) {
                    /*校验令牌是否过期*/
                    if (stringRedisTemplate.hasKey(value)) {
                       /*获取令牌*/
                        String token = stringRedisTemplate.boundValueOps(value).get();
                        /*将令牌添加到请求头*/
                        request.mutate().header(Authorization, "Bearer " + token);
                    } else {
                        /*令牌过期*/
                        getBack(request, response);
                        return response.setComplete();
                    }
                } else {
                    /*cookie没有value*/
                    getBack(request, response);
                    return response.setComplete();
                }
            } else {
                /*cookie为空*/
                getBack(request, response);
                return response.setComplete();
            }
        }
        return chain.filter(exchange);
    }

    private void getBack(ServerHttpRequest request, ServerHttpResponse response) {
        /*出现异常需要回到登陆界面，也要在地址后面拼上ReturnUrl*/
        String ReturnUrl = null;
        try {
            ReturnUrl = URLEncoder.encode(request.getURI().getRawSchemeSpecificPart(), "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String url = LOCALURL + ReturnUrl;
        response.setStatusCode(HttpStatus.SEE_OTHER);
        response.getHeaders().set(HttpHeaders.LOCATION, url);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
